#include <iostream>
#include <cassert>
#include <string>
#include <typeinfo>
#include <unistd.h>


//Any类不能是模板，不然外面使用的时候需要传递类型就没有意义了
//这里使用多态的方式来解决问题，子类是模板类，这样使用父类指针就可以访问到子类。
class Any
{
private:
    //父类不是模板类，这样可以保证Any类不是模板
    class holer
    {
    public:
        virtual ~holer() {}
        virtual const std::type_info& type() = 0; //设置成纯虚函数，那么子类想要实例化就必须要重写虚函数 
        virtual holer* clone() = 0;
    };
    template <class T>
    class placeholer : public holer
    {
    public:
        placeholer(const T& val):_val(val){}
        virtual ~placeholer() {}
        virtual const std::type_info& type() { return typeid(T);}
        virtual placeholer* clone() { return new placeholer(_val);}
    public:
        T _val;
    };
private:
    Any& swap(Any& any)
    {
        std::swap(_holer,any._holer);
        return *this;
    }
    holer* _holer;
public:
    Any():_holer(nullptr) {}
    ~Any(){ delete _holer; }
    Any(const Any& any):_holer(any._holer == nullptr?nullptr:any._holer->clone()){}
    template <class T>
    Any(const T& val):_holer(new placeholer<T>(val)) {}
    template<class T>
    T* get()
    {
        assert(typeid(T) == _holer->type());
        return &((placeholer<T>*)_holer)->_val;
    }
    Any& operator=(Any& any)
    {
        Any(any).swap(*this);
        return *this;
    }
    template<class T>
    Any& operator=(const T& val)
    {
        Any(val).swap(*this);
        return *this;
    }
};

//测试是否有资源泄露
class Test
{
public:
    Test(){ std::cout<< "构造" <<std::endl;}
    Test(const Test &t) {std::cout<< "拷贝" <<std::endl;}
    ~Test(){ std::cout<< "析构" <<std::endl;}
};

int main()
{
    Any a;
    {
        Test t;
        a = t;
    }
    while(1) sleep(1);
    // a = 10;
    // int *pa = a.get<int>();
    // std::cout<< *pa <<std::endl;
    // a = std::string("nihao");
    // std::string* ps = a.get<std::string>();
    // std::cout<< *ps <<std::endl;
    return 0;
}